package com.tinyengine.it.controller.generator;

import com.tinyengine.it.common.utils.GenDir;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class JavaCodeFormatter {

    private static final Logger logger = LoggerFactory.getLogger(JavaCodeFormatter.class);

    // Google Java Format JAR 文件名
    private static final String FORMATTER_JAR = "google-java-format-1.26.0-all-deps.jar";

    /**
     * 格式化指定目录下的所有 Java 文件
     *
     * @param directoryPath 要格式化的目录路径
     * @throws IOException 如果发生 I/O 错误
     */
    public static void formatJavaFiles(String directoryPath) {
        try {
            // 获取格式化工具的 JAR 文件路径
            //String formatterJarPath = getFormatterJarPath();
            String formatterJarPath = GenDir.templatesResourcesRootDir + FORMATTER_JAR;

            // 收集所有 Java 文件
            List<File> javaFiles = collectJavaFiles(directoryPath);

            if (javaFiles.isEmpty()) {
                logger.info("No Java files found in directory: {}", directoryPath);
                return;
            }

            // 为每个文件执行格式化命令
            javaFiles.parallelStream().forEach(e -> formatSingleFile(formatterJarPath, e));

            logger.info("Formatted {} Java files in directory: {}", javaFiles.size(), directoryPath);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取格式化工具的 JAR 文件路径
     *
     * @return JAR 文件路径
     * @throws IOException 如果无法复制 JAR 文件到临时目录
     */
    private static String getFormatterJarPath() throws IOException {
        // 从 classpath 加载 JAR 文件
        ClassPathResource resource = new ClassPathResource(FORMATTER_JAR);

        // 创建临时目录来存放 JAR 文件
        Path tempDir = Files.createTempDirectory("java-formatter");
        tempDir.toFile().deleteOnExit();

        // 目标 JAR 文件路径
        Path jarPath = tempDir.resolve(FORMATTER_JAR);

        try (InputStream in = resource.getInputStream();
             OutputStream out = Files.newOutputStream(jarPath)) {
            // 复制 JAR 文件到临时目录
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = in.read(buffer)) != -1) {
                out.write(buffer, 0, bytesRead);
            }
        }

        return jarPath.toString();
    }

    /**
     * 收集指定目录下的所有 Java 文件
     *
     * @param directoryPath 目录路径
     * @return Java 文件列表
     * @throws IOException 如果访问文件系统时出错
     */
    private static List<File> collectJavaFiles(String directoryPath) throws IOException {
        Path startPath = Paths.get(directoryPath);

        if (!Files.exists(startPath) || !Files.isDirectory(startPath)) {
            throw new IllegalArgumentException("Directory does not exist: " + directoryPath);
        }

        return Files.walk(startPath)
                .filter(path -> path.toString().endsWith(".java"))
                .map(Path::toFile)
                .collect(Collectors.toList());
    }

    /**
     * 格式化单个 Java 文件
     *
     * @param formatterJarPath 格式化工具 JAR 路径
     * @param javaFile         要格式化的 Java 文件
     * @throws IOException          如果执行命令时出错
     * @throws InterruptedException 如果进程被中断
     */
    public static void formatSingleFile(String formatterJarPath, File javaFile) {
        // 构建命令
        List<String> command = new ArrayList<>();
        command.add(getJavaExecutablePath());
        command.add("-jar");
        command.add(formatterJarPath);
        command.add("--replace");
        //command.add("--aosp");
        command.add(javaFile.getAbsolutePath());

        ProcessBuilder processBuilder = new ProcessBuilder(command);
        processBuilder.redirectErrorStream(true);

        try {
            Process process = processBuilder.start();

            // 读取命令输出
            try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
                String line;
                while ((line = reader.readLine()) != null) {
                    logger.debug(line);
                }
            }
            int exitCode = process.waitFor();
            if (exitCode != 0) {
                logger.error("Failed to format file: {}. Exit code: {}", javaFile.getAbsolutePath(), exitCode);
            } else {
                logger.info("Successfully formatted: {}", javaFile.getAbsolutePath());
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取 Java 可执行文件路径（兼容 Windows 和 Linux）
     *
     * @return Java 可执行文件路径
     */
    private static String getJavaExecutablePath() {
        String javaHome = System.getProperty("java.home");
        String javaExecutable = javaHome + File.separator + "bin" + File.separator + "java";

        // Windows 系统需要添加 .exe 后缀
        if (System.getProperty("os.name").toLowerCase().contains("win")) {
            javaExecutable += ".exe";
        }

        return javaExecutable;
    }
}